/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ventas.beans;

import entities.FacturaMultimarca;
import entities.LineaFacturaMultimarca;
import entities.Pedido;
import entities.Producto;
import entities.ProductoTalla;
import entities.Talla;
import entities.Usuario;
import facades.FacturaMultimarcaFacade;
import facades.LineaFacturaMultimarcaFacade;
import facades.LineaPedidoFacade;
import facades.PedidoFacade;
import facades.ProductoTallaFacade;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.New;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.map.MultiKeyMap;
import qualifiers.EventoEntidadCreada;
import qualifiers.EventoEntidadEditada;
import qualifiers.EventoEntidadElegida;
import qualifiers.UsuarioLogeado;
import qualifiers.resources.MapaProductosTalla;
import ventas.datamodel.TablaPedidoDataModel;

/**
 *
 * @author damfercer
 */
@Named(value = "nuevaFacturaMultimarcaBean")
@SessionScoped
public class NuevaFacturaMultimarcaBean implements Serializable {
    @Inject
    PedidoFacade pedidoFacade;
    @Inject
    private LineaPedidoFacade lineaPedidoFacade;
    @Inject
    private TablaPedidoDataModel tablaPedidoDataModel;
    private Pedido pedido;
    @Inject
    private FacturaMultimarcaFacade facturaMultimarcaFacade;
    @Inject
    private LineaFacturaMultimarcaFacade lineaFacturaMultimarcaFacade;
    @Inject
    @New
    private FacturaMultimarca facturaMultimarca;
    @Inject
    @EventoEntidadCreada
    private Event<FacturaMultimarca> eventoNuevaFactura;
    @Inject
    @UsuarioLogeado
    Usuario usuario;
    private Map<Integer,LineaFacturaMultimarca> lineasFactura;
    @Inject
    private ProductoTallaFacade productoTallaFacade;
    @Inject
    private MultiplicadoresBean multiplicadoresBean;
    private Map<Integer,Integer> unidadesPedido;
    private Map<Integer,Integer> unidadesEnviadas;
    @Inject
    @MapaProductosTalla
    private MultiKeyMap mapaProductosTalla;
    private BigInteger codigoBarras;
    @Inject
    @EventoEntidadEditada
    private Event<Pedido> eventoPedidoMultimarcaEditado;
    /**
     * Creates a new instance of NuevaFacturaMultimarcaBean
     */
    public NuevaFacturaMultimarcaBean() {
    }
    
    public void reinitBean(){
        setFacturaMultimarca(new FacturaMultimarca());
        this.lineasFactura=new HashMap<Integer,LineaFacturaMultimarca>();
    }
    
    public void onPedidoElegido(@Observes @EventoEntidadElegida Pedido p){
        this.setPedido(p);
        pedido.getLineaPedidoList();
        //this.lineasFactura=new ArrayList<LineaFacturaMultimarca>();
        this.lineasFactura=new HashMap<Integer,LineaFacturaMultimarca>();
        this.getFacturaMultimarca().setPedido(pedido);
        this.getFacturaMultimarca().setDescuento(getPedido().getDescuento());
        this.getFacturaMultimarca().setFormaPago(getPedido().getFormaPago());
        this.getFacturaMultimarca().setPrecioPorte(getPedido().getPrecioPorte());
        this.tablaPedidoDataModel.setPedido(pedido);
        unidadesPedido=new HashMap<Integer,Integer>();
        unidadesEnviadas=new HashMap<Integer,Integer>();
    }
    
    public Boolean puedeGuardar(){
        Boolean res=true;
        for(LineaFacturaMultimarca linea: lineasFactura.values()){
            Integer restan=this.recuperarCantidadPedidaDeProductoTalla(linea.getProductoTalla().getProducto(), linea.getProductoTalla().getTalla())-this.recuperarCantidadServidaDeProductoTalla(linea.getProductoTalla().getProducto(), linea.getProductoTalla().getTalla());
            if(restan<linea.getCantidad()){
                res=false;
            }
        }
        return res;
    }
    
    public void guardarLinea(Producto p, Talla t){
        LineaFacturaMultimarca linea=recuperarLineaFacturaDeProductoTalla(p, t);
        Integer restan=this.recuperarCantidadPedidaDeProductoTalla(p, t)-this.recuperarCantidadServidaDeProductoTalla(p, t);
        if(linea.getCantidad()<=restan){
                 
        }
        else{
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            Locale locale=context.getViewRoot().getLocale();
            ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
            String errorNoPedidoElegido=rb.getString("ErrorCantidadSuperada");
            FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, msg);
            context.renderResponse();
        }
    }
    
    public String guardarTodo(){
        guardarFactura();
        guardarLineas();
        eventoNuevaFactura.fire(getFacturaMultimarca());
        if(pedido.getFacturaMultimarcaList()==null){
            pedido.setFacturaMultimarcaList(new ArrayList<FacturaMultimarca>());
        }
        pedido.getFacturaMultimarcaList().add(getFacturaMultimarca());
        eventoPedidoMultimarcaEditado.fire(pedido);
        pedidoFacade.evict(pedido, pedido.getIdPedido());
        facturaMultimarcaFacade.evict(facturaMultimarca, facturaMultimarca.getIdFacturaMultimarca());
        reinitBean();
        return "/views/ventas/Pedidos?faces-redirect=true";
    }
    
    public void guardarFactura(){
        Date ahora=new Date();
        getFacturaMultimarca().setIdentificador(facturaMultimarcaFacade.getIdentificador());
        getFacturaMultimarca().setUsuarioCreador(usuario);
        getFacturaMultimarca().setFecha(ahora);
        facturaMultimarcaFacade.create(getFacturaMultimarca());
        //eventoNuevaFactura.fire(getFacturaMultimarca());
    }
    
    public void guardarLineas(){
        for (LineaFacturaMultimarca lineaFacturaMultimarca : lineasFactura.values()) {
            if(lineaFacturaMultimarca.getCantidad()!=0){
                lineaFacturaMultimarca.setDescuento(getFacturaMultimarca().getDescuento());
                lineaFacturaMultimarca.setPvp(lineaFacturaMultimarca.getProductoTalla().getProducto().getPvp());
                BigDecimal multiplicador=multiplicadoresBean.recuperarMultiplicadorDeProductoYPedido(lineaFacturaMultimarca.getProductoTalla().getProducto(), pedido);
                BigDecimal coste=lineaFacturaMultimarca.getProductoTalla().getProducto().getPvp().divide(multiplicador, RoundingMode.HALF_UP);
                lineaFacturaMultimarca.setCoste(coste);
                lineaFacturaMultimarcaFacade.create(lineaFacturaMultimarca);
                if(getFacturaMultimarca().getLineaFacturaMultimarcaList()==null){
                    getFacturaMultimarca().setLineaFacturaMultimarcaList(new ArrayList<LineaFacturaMultimarca>());
                }
                getFacturaMultimarca().getLineaFacturaMultimarcaList().add(lineaFacturaMultimarca);
            }
        }
    }
    
    public LineaFacturaMultimarca recuperarLineaFacturaDeProductoTalla(Producto p, Talla t){
        LineaFacturaMultimarca encontrada=null;
        if(p!=null && t!=null){
            ProductoTalla pt=(ProductoTalla)mapaProductosTalla.get(p.getIdProducto(),t.getIdTalla());
            if(pt!=null){
                if(!lineasFactura.containsKey(pt.getIdProductoTalla())){
                    LineaFacturaMultimarca linea=new LineaFacturaMultimarca();
                    linea.setCantidad(0);
                    linea.setFactura(getFacturaMultimarca());
                    linea.setProductoTalla(pt);
                    lineasFactura.put(pt.getIdProductoTalla(), linea);
                }
                encontrada=lineasFactura.get(pt.getIdProductoTalla());
            }
        }
        return encontrada;
    }

    /**
     * @return the facturaMultimarca
     */
    public FacturaMultimarca getFacturaMultimarca() {
        return facturaMultimarca;
    }

    /**
     * @param facturaMultimarca the facturaMultimarca to set
     */
    public void setFacturaMultimarca(FacturaMultimarca facturaMultimarca) {
        this.facturaMultimarca = facturaMultimarca;
    }

    /**
     * @return the pedido
     */
    public Pedido getPedido() {
        return pedido;
    }

    /**
     * @param pedido the pedido to set
     */
    public void setPedido(Pedido pedido) {
        this.pedido = pedido;
    }

    /**
     * @return the tablaPedidoDataModel
     */
    public TablaPedidoDataModel getTablaPedidoDataModel() {
        return tablaPedidoDataModel;
    }

    /**
     * @param tablaPedidoDataModel the tablaPedidoDataModel to set
     */
    public void setTablaPedidoDataModel(TablaPedidoDataModel tablaPedidoDataModel) {
        this.tablaPedidoDataModel = tablaPedidoDataModel;
    }
    
    public Integer recuperarCantidadPedidaDeProductoTalla(Producto p, Talla t){
        Integer cantidad=0;
        if(p!=null && t!=null){
            ProductoTalla pt=(ProductoTalla)mapaProductosTalla.get(p.getIdProducto(),t.getIdTalla());            
            if(pt!=null){
                if(!unidadesPedido.containsKey(pt.getIdProductoTalla())){
                    cantidad=lineaPedidoFacade.getCantidadProductoTallaPedido(pt, getPedido());
                    unidadesPedido.put(pt.getIdProductoTalla(), cantidad);
                }
                else{
                    cantidad=unidadesPedido.get(pt.getIdProductoTalla());
                }
            }
        }
        return cantidad;
    }
    
    public Integer recuperarCantidadServidaDeProductoTalla(Producto p, Talla t){
        Integer cantidad=0;
        ProductoTalla pt=(ProductoTalla)mapaProductosTalla.get(p.getIdProducto(),t.getIdTalla());
        if(!unidadesEnviadas.containsKey(pt.getIdProductoTalla())){
            cantidad=lineaFacturaMultimarcaFacade.getCantidadEnvidadaDeProductoTallaPedido(pt, getPedido());
            if(cantidad==null){
                cantidad=0;
            }
            unidadesEnviadas.put(pt.getIdProductoTalla(), cantidad);
        }
        else{
            cantidad=unidadesEnviadas.get(pt.getIdProductoTalla());
        }
        return cantidad;
    }
    
    public void procesarCodigoBarras(){
        ProductoTalla pt=productoTallaFacade.getProductoTallaDeCodigoDeBarras(codigoBarras);
        if(pt!=null){
            if(lineasFactura.containsKey(pt.getIdProductoTalla())){
                Integer restan=this.recuperarCantidadPedidaDeProductoTalla(pt.getProducto(), pt.getTalla())-this.recuperarCantidadServidaDeProductoTalla(pt.getProducto(), pt.getTalla());
                LineaFacturaMultimarca linea=lineasFactura.get(pt.getIdProductoTalla());
                if(linea.getCantidad()>=restan){
                    FacesContext context = FacesContext.getCurrentInstance();
                    HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
                    Locale locale=context.getViewRoot().getLocale();
                    ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
                    String errorNoPedidoElegido=rb.getString("ErrorCantidadSuperada");
                    FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
                    msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                    context.addMessage(null, msg);
                    context.renderResponse();   
                }
                else{
                    linea.setCantidad(linea.getCantidad()+1);
                }
            }
            else{
                FacesContext context = FacesContext.getCurrentInstance();
                HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
                Locale locale=context.getViewRoot().getLocale();
                ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
                String errorNoPedidoElegido=rb.getString("ProductoTallaNoEstaEnPedido");
                FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
                msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                context.addMessage(null, msg);
                context.renderResponse();
            }
        }
        else{
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            Locale locale=context.getViewRoot().getLocale();
            ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
            String errorNoPedidoElegido=rb.getString("ErrorNoExisteProductoTallaDeCodigoDeBarras");
            FacesMessage msg =new FacesMessage(errorNoPedidoElegido,errorNoPedidoElegido);
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, msg);
            context.renderResponse();
        }
        this.codigoBarras=null;
    }

    /**
     * @return the codigoBarras
     */
    public BigInteger getCodigoBarras() {
        return codigoBarras;
    }

    /**
     * @param codigoBarras the codigoBarras to set
     */
    public void setCodigoBarras(BigInteger codigoBarras) {
        this.codigoBarras = codigoBarras;
    }
}
